#include "rand_ks.h"

/* Public domain code for JKISS RNG */
/* From http://www0.cs.ucl.ac.uk/staff/d.jones/GoodPracticeRNG.pdf */


void JK_Init(jkiss *jk)
{
        /*
        jk->x = time(NULL);
        jk->x = 987654321;
        jk->z = 43219876;
        jk->c = 654321;
        */
        jk->x = (int)(10.0 *random() /(RAND_MAX+ 1));
        while( !( jk->y = (int)(10.0 *random() /(RAND_MAX+ 1)) ) );
        jk->z = (int)(10.0 *random() /(RAND_MAX+ 1));
        jk->c = (int)(10.0 *random() /(RAND_MAX+ 1)) %698769068 +1;
}

unsigned int JKISS(jkiss *jk)
{
        unsigned long long t;
        jk->x = 314527869 * jk->x + 1234567;
        jk->x ^= jk->x << 5; jk->x ^= jk->x >> 7; jk->x ^= jk->x << 22;
        t = 4294584393ULL * jk->x + jk->x; jk->x = t >> 32; jk->x = t;
        return jk->x + jk->x + jk->x;
}

double next(jkiss *jk)
{
        double r;
        unsigned long long a;
        a = ((unsigned long long)JKISS(jk)<<32) + JKISS(jk);
        a = (a >> 12) | 0x3FF0000000000000ULL; /* Take upper 52 bits */
        *((unsigned long long *)&r) = a; /* Make a double from bits */
        return r-1.0;
}

